package linked_node;


import java.util.Objects;

public class simpleSingleHeroLinkedList {
    public static void main(String[] args) {
        controlHeroNode heroNo = new controlHeroNode();
        heroNode hero1 = new heroNode(1, "宋江", "天魁星");
        heroNode hero2 = new heroNode(2, "卢俊义", "玉麒麟");
        heroNode hero3 = new heroNode(3, "吴用", "智多星");
        heroNo.addNodeByOrder(hero3);
        heroNo.addNodeByOrder(hero2);
        heroNo.addNodeByOrder(hero1);
        heroNo.scanLinkList();
//        heroNode hero4 = new heroNode(2, "卢俊义~", "玉麒麟~");
//        heroNo.alterNode(hero4);
//        System.out.println("修改后的：");
//        heroNo.scanLinkList();
//        System.out.println("删除后为英雄排行榜为：");
//        heroNo.delNode(hero3);
//        heroNo.scanLinkList();
        System.out.println(heroNo.findHero(3));
//        String name = "卢俊义";
//        String nickname = "天魁星";
//        System.out.println(heroNo.findHero(name));
//        System.out.println(heroNo.findHero(nickname));
    }
}

// 使用一个类来控制节点，管理英雄
class controlHeroNode {
    // 为单链表创建一个头结点,不用赋予它信息
    heroNode head = new heroNode(0, "", "");

    // 根据英雄的各种信息查询英雄
    public heroNode findHero(int no) {
        heroNode tmpNode = head.next;
        while(true) {
            if (tmpNode.no == no) {
                return tmpNode;
            }
            if (tmpNode.next == null) {
                break;
            }
            tmpNode = tmpNode.next;
        }
        return null;
    }

    // 此处有可能是名字或者外号
    public heroNode findHero(String nameOrNickname) {
        heroNode tmpNode = head.next;
        while(tmpNode.next != null) {
            if (tmpNode.name.equals(nameOrNickname) || tmpNode.nickname.equals(nameOrNickname)) {
                return tmpNode;
            }
            tmpNode = tmpNode.next;
        }
        return null;
    }

    // 删除英雄的信息
    public void delNode(heroNode hero) {
        // 判断是否为空
        if (head.next == null) {
            System.out.println("当前英雄榜为空~~~");
            return;
        }
        boolean flag = true;
        heroNode tmpNode = head;
        while (tmpNode.next != null) {
            // 找到当前英雄的上一个英雄节点
            if (hero.equals(tmpNode.next)) {
                flag = false;
                tmpNode.next = hero.next;
                break;
            }
            tmpNode = tmpNode.next;
        }
        if (flag) {
            System.out.println("没有找到当前英雄信息，删除失败！");
        }
    }

    // 根据排名修改一个排名的英雄信息
    public void alterNode(heroNode hero) {
        // 先判断当前单链表是否为空
        // 使用tempNode作为辅助节点遍历单链表
        heroNode tempNode = head;
        if (tempNode.next == null) {
            System.out.println("当前英雄榜为空~~~");
            return;
        }
        while (true) {
            // 当前已经到达最后一个节点
            if (tempNode.next == null) {
                System.out.println("没有找到相应的英雄");
                return;
            }
            // 判断当前节点等于这个排名
            if (tempNode.next.no == hero.no) {
                hero.next = tempNode.next.next;
                tempNode.next = hero;
                return;
            }
            tempNode = tempNode.next;
        }
    }

    // 按英雄的排名添加英雄节点
    public void addNodeByOrder (heroNode hero) {
        // 使用临时节点移动来遍历单链表，寻找合适位置
        heroNode tmpNode = head;
        while (true) {
            // 先判断当前节点是否为链表的最后一个节点
            // 若为空则是向该节点插入英雄节点
            if (tmpNode.next == null) {
                break;
            }
            // 当前临时节点的下一节点的排名大于英雄排名时，则找到合适位置
            if (tmpNode.next.no > hero.no) {
                break;
            }
            // 若tmpNode的no不大于hero的no,需要判断当前英雄排名是否已经存在（即等于当前tmpNode的排名）,若存在，则不能插入
            if (tmpNode.next.no == hero.no) {
                System.out.printf("第 %d 名已被人占领~\n", hero.no);
                return;
            }
            // 上述判断后都没有找到，则移动临时节点指向下一节点
            tmpNode = tmpNode.next;
        }
        hero.next = tmpNode.next;
        tmpNode.next = hero;

    }

    // 为单链表添加一个节点
    public void addNode (heroNode hero) {
        // 寻找当前链表中的节点的next为空的那一个节点
        // 因为头结点不能移动，所以用一个临时节点来移动遍历链表,让它先指向head
        heroNode tmpNode = head;
        while (true) {
            if (tmpNode.next == null) {
                break;
            }
            tmpNode = tmpNode.next;
        }
        tmpNode.next = hero;
    }

    // 遍历当前链表,不用加上头结点！！！
    public void scanLinkList() {
        // 首先判断链表是否为空
        if (head.next == null) {
            System.out.println("当前英雄榜上空空如也~");
            return;
        }
        heroNode tmpNode = head.next;
        while (true) {
            // 判断当前节点是否为最后一个节点
            if (tmpNode == null) {
                return;
            }
            System.out.println(tmpNode);
            tmpNode = tmpNode.next;
        }
    }
}

// 使用一个用来表示英雄属性的节点的类
class heroNode {
    public int no; // 表示英雄排名
    public String name;
    public String nickname; // 表示英雄的别名
    public heroNode next; // 表示与这个节点相连的下一个节点

    // 创建英雄节点的构造方法
    public heroNode (int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }

    // 比较英雄
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof heroNode)) return false;
        heroNode heroNode = (heroNode) o;
        return no == heroNode.no && name.equals(heroNode.name) && nickname.equals(heroNode.nickname);
    }

//    private boolean equals(heroNode hero) {
//        if (this.no == hero.no && this.name.equals(hero.name) && this.nickname.equals(hero.nickname) ){
//            return true;
//        }
//        return false;
//    }

    // 重写toString()方法用于打印英雄信息
    @Override
    public String toString() {
        return "heroNode{" +
                "no=" + no +
                ", name='" + name + "'" +
                ", nickname='" + nickname + "'}"; // 最后的next不用打印，要是加上的话会自动打印后面节点的信息
    }
}